;;; init-packages.el --- init packages
;;; -*- lexical-binding: t -*-

;;; Commentary:

;;; Code:

(eval-when-compile
  (require 'use-package))

(use-package ivy
  :ensure t                          ; 确认安装，如果没有安装过 ivy 就自动安装
  :init                              ; 在加载插件前执行命令
  (ivy-mode 1)                       ; 启动 ivy-mode
  :custom                            ; 自定义一些变量，相当于赋值语句 (setq xxx yyy)
  (ivy-use-virtual-buffers t)        ; 一些官网提供的固定配置
  (ivy-count-format "(%d/%d) ")
  :bind                              ; 以下为绑定快捷键
  ("C-s" . 'swiper-isearch)          ; 绑定快捷键 C-s 为 swiper-search，替换原本的搜索功能
  ("M-x" . 'counsel-M-x)             ; 使用 counsel 替换命令输入，给予更多提示
  ("C-x C-f" . 'counsel-find-file)   ; 使用 counsel 做文件打开操作，给予更多提示
  ("M-y" . 'counsel-yank-pop)        ; 使用 counsel 做历史剪贴板粘贴，可以展示历史
  ("C-x b" . 'ivy-switch-buffer)     ; 使用 ivy 做 buffer 切换，给予更多提示
  ("C-c v" . 'ivy-push-view)         ; 记录当前 buffer 的信息
  ("C-c s" . 'ivy-switch-view)       ; 切换到记录过的 buffer 位置
  ("C-c V" . 'ivy-pop-view)          ; 移除 buffer 记录
  ("C-x C-SPC" . 'counsel-mark-ring) ; 使用 counsel 记录 mark 的位置
  ("<f1> f" . 'counsel-describe-function)
  ("<f1> v" . 'counsel-describe-variable)
  ("<f1> i" . 'counsel-info-lookup-symbol))


(use-package which-key
  :ensure t
  :init (which-key-mode))


(use-package evil :ensure t
  :init
  (setq evil-disable-insert-state-bindings t 	;; insert state保留emacs键绑定。
	evil-want-keybinding nil	 	;; 不要执行evil-keybindings.el
	evil-want-C-i-jump nil 			;; 把TAB键释放出来。
	)
  :config
  (setq evil-emacs-state-modes '( 		;; ediff-mode和color-rg-mode不需要evil。
				 ediff-mode
				 color-rg-mode
				 ibuffer-mode
				 )) 
  (add-hook 'with-editor-mode-hook 'evil-insert-state) ;; 可编辑模式默认insert state。
  ;; 使用define-prefix-command实现类似spacemacs键绑定
  (define-prefix-command 'space-leader-map)
  (keymap-set evil-motion-state-map "SPC" 'space-leader-map)
  (keymap-set evil-normal-state-map "SPC" 'space-leader-map)
  (defun my/switch-to-message-buffer ()
    (interactive)
    (switch-to-buffer "*Messages*"))
  (defun my/switch-to-scratch-buffer ()
    (interactive)
    (switch-to-buffer "*scratch*"))
  (defun my/enter-major-mode-map ()
    (interactive)
    (keymap-set space-leader-map "m"
		(symbol-value (intern-soft (format "%s-map" major-mode)))))
  ;; 最关键一步。在normal模式下按 SPC + m 会进入当前mode的major-mode-map，继续按键就是emacs的操作了。
  (add-hook 'buffer-list-update-hook
	    'my/enter-major-mode-map ;; #'(lambda () (interactive) (keymap-set space-leader-map "m" (symbol-value (intern-soft (format "%s-map" major-mode)))))
	    )
  ;; 之前已经把TAB键释放出来，再把RET和q释放出来。
  (define-key evil-motion-state-map (kbd "RET") nil)
  ;; buffer
  (define-prefix-command 'my/leader-buffer-map)
  (evil-define-key nil my/leader-buffer-map
    "b" 'ivy-switch-buffer
    "i" 'ibuffer
    "d" 'evil-delete-buffer
    "l" 'evil-switch-to-windows-last-buffer
    "m" '("message" . my/switch-to-message-buffer)
    "x" '("scratch" . my/switch-to-scratch-buffer) ;; #'(lambda () (interactive) (switch-to-buffer "*scratch*"))
    )
  ;; file
  (define-prefix-command 'my/leader-file-map)
  (evil-define-key nil my/leader-file-map
    "f" 'counsel-find-file
    "r" 'recentf-open
    "w" 'save-buffer
    )
  ;; help
  (define-prefix-command 'my/leader-help-map)
  (evil-define-key nil my/leader-help-map
    "f" '("function" . counsel-describe-function)
    "v" '("variable" . counsel-describe-variable)
    "i" '("info" . counsel-info-lookup-symbol)
    )
  ;; vc
  (define-prefix-command 'my/leader-vc-map)
  (evil-define-key nil my/leader-vc-map
    "v" 'vc-next-action
    "d" 'vc-dir
    )
  ;; quit
  (define-prefix-command 'my/leader-quit-map)
  (evil-define-key nil my/leader-quit-map
    "qr" 'restart-emacs
    "qq" '("Quit" . save-buffers-kill-terminal)
    )
  ;; terminal
  (define-prefix-command 'my/leader-term-map)
  (defun my/open-terminal ()
    (interactive)
    (make-comint-in-buffer "cmd" nil "cmd" nil)
    (switch-to-buffer "*cmd*")
    )
  (evil-define-key nil my/leader-term-map
    "t" '("terminal" . my/open-terminal)
    )
  (evil-define-key nil space-leader-map
    (kbd "SPC") '("execute" . counsel-M-x) 	;; 'execute-extended-command
    (kbd "RET") '("eval" . eval-buffer)  	;; consult-bookmark
    ";" '("comment" . comment-line)
    ;; "0" 'treemacs-select-window		;; undefined
    ;; buffer
    "b" '("buffer" . my/leader-buffer-map)
    ;; file
    "f" '("file" . my/leader-file-map)
    ;; help
    "h" '("help" . my/leader-help-map)
    ;; vc
    "v" '("vc" . my/leader-vc-map)
    ;; quit
    "q" '("quit" . my/leader-quit-map)
    ;; terminal
    "t" '("terminal" . my/leader-term-map)
    )
  (evil-define-key 'normal text-mode-map (kbd "RET") #'embark-dwim) ;; embark-dwim相当于vscode中 Ctrl + 鼠标左键。
  (evil-define-key 'normal prog-mode-map (kbd "RET") #'embark-dwim)
  (evil-define-key 'normal special-mode-map "q" #'quit-window)
  (evil-mode))





(use-package flycheck
  :ensure t
  :hook                        ; 为模式设置 hook
  (prog-mode . flycheck-mode))

(provide 'init-packages)
;;; init-packages.el ends here
